// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rainbowchat.http.logic;

import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.dbpool.DBDepend;
import com.eva.framework.dbpool.DBShell;
import com.eva.framework.utils.LoggerFactory;
import com.x52im.rainbowchat.BaseConf;

/**
 * 定时转储服务端存储的客户端的超期聊天记录、离线消息。
 * 
 * @author Jason
 * @since 4.5
 */
public class TimmingRestoreMessages
{
	/** 将聊天记录表数据复制到聊天记录存档表的可重用SQL（重用的目的是希
	 * 望别的地方用到时能保持一致，防止以后增、减字段时维护不方便） */ 
	public final static String COPY_CHATTING_MESSAGES_TO_ACHIVED_SQL = 
			"INSERT INTO missu_user_msgs_collect_archived(src_uid,dest_uid,chat_type,msg_type,msg_content,msg_time,msg_time2,online_count,fingerprint,parent_fp)" +
			"	 select src_uid,dest_uid,chat_type,msg_type,msg_content,msg_time,msg_time2,online_count,fingerprint,parent_fp from missu_user_msgs_collect";
	
	/** 将聊天记录表数据清除的可重用SQL（重用的目的是希
	 * 望别的地方用到时能保持一致，防止以后维护不方便） */ 
	public final static String DELETE_CHATTING_MESSAGES_SQL = "DELETE FROM missu_user_msgs_collect";
	
	private static TimmingRestoreMessages instance = null;
	
	private Timer timer = null;
	private DBShell db = new DBShell();

	public static TimmingRestoreMessages getInstance()
	{
		if(instance == null)
			instance = new TimmingRestoreMessages();
		return instance;
	}
	
	public void doTaskOnece()
	{
		LoggerFactory.getLog().debug("[定时器2]======= 【1/2】聊天记录、离线消息超期转储处理[开始] =======");
		long t = System.currentTimeMillis();
		
		try
		{
			Vector sqls = new Vector();
			Vector values = new Vector();
			
			
			//********************* 先尝试转储过期的聊天记录 ************************//
			// 通过SQL的函数计算数据库中聊天消息与当前时间的时间差
			String timediffSQL1 = DBDepend.getTIMEDIFF("SECOND", "msg_time");
						
			// 先将超出期限的聊天记录先插入到存档表中
			sqls.add(COPY_CHATTING_MESSAGES_TO_ACHIVED_SQL+" where "+timediffSQL1+">?");
			values.add(new Object[]{BaseConf.getInstance().getAUTO_TIMING_RESTORE_MESSAGES_TIMEOUT()});

			// 再将超出期限的聊天记录从聊天记录表中移除
			sqls.add(DELETE_CHATTING_MESSAGES_SQL+" where "+timediffSQL1+">?");
			values.add(new Object[]{BaseConf.getInstance().getAUTO_TIMING_RESTORE_MESSAGES_TIMEOUT()});

			
			//********************* 先尝试转储过期的离线消息 ************************//
			// 通过SQL的函数计算数据库中聊天消息与当前时间的时间差
			String timediffSQL2 = DBDepend.getTIMEDIFF("SECOND", "history_time");
			// 直接将超出期限的离线消息从离线消息表中移除
			sqls.add("DELETE FROM missu_offline_history where "+timediffSQL2+">?");
			values.add(new Object[]{BaseConf.getInstance().getAUTO_TIMING_RESTORE_MESSAGES_TIMEOUT()});
			
			
			//********************* 提交数据库执行 *********************************//
			db.update(sqls, values, true);
		}
		catch (Exception e)
		{
			LoggerFactory.getLog().warn("[定时器2]======= 聊天记录、离线消息超期转储处理过程中出现的非正常逻辑："
					+e.getMessage()+"，原因可能是没有需要处理的数据行，您可忽略本行log。");
		}
		
		LoggerFactory.getLog().debug("[定时器2]======= 【2/2】聊天记录、离线消息超期转储处理[完成] ,[耗时："+(System.currentTimeMillis() - t)+"毫秒]");
	}
	
	public void start()
	{
		// ** 先确保之前定时任务被停止
		stop();
		
		// ** 启动定时任务
		timer = new Timer();
		// ** 以定长延迟的方式进行（即下一次执行是在本次执行结束之后开始计时）
		timer.schedule(new TimerTask() {
			@Override
			public void run()
			{
				doTaskOnece();
			}
		}
		// 首次执行时的延迟
		, 1000 * 60 * 10
		// 定时执行的时间间隔
		, CommonUtils.getIntValue(BaseConf.getInstance().getAUTO_TIMING_RESTORE_MESSAGES_INTERVAL(), 10 * 60 * 10));
	}
	
	/**
	 * 无条件中断本定时器的运行。
	 */
	public void stop()
	{
		if(timer != null)
		{
			try{
				timer.cancel();
			}
			finally{
				timer = null;
			}
		}
	}
	
	/**
	 * 定时器是否正在运行中。
	 * 
	 * @return true表示是，否则定时器处于停止状态
	 */
	public boolean isRunning()
	{
		return timer != null;
	}
}
